﻿namespace UnitTests.Domain
{
	using Core.Domain;
	using Xunit;

	public class When_User_Register_Account
	{
		[Fact]
		public void Should_Create_Account()
		{
			const string fakeEmail = "user@example.com";
			const string fakeDisplayName = "User";
			const string etalonPassword = "password";

			var environment = new TestEnvironment();

			var registrationService = environment
				.CreateRegistrationService();

			var result = registrationService.Register(fakeEmail, fakeDisplayName, etalonPassword);

			Assert.Equal(RegistrationResultCode.Success, result.Code);
			Assert.NotNull(result.Account);			
			Assert.NotEmpty(environment.AccountRepository.Storage);
			Assert.Equal(etalonPassword, environment.AccountRepository.Storage[0].Password);
		}

		[Fact]
		public void Should_Create_Person()
		{
			const string etalonEmail = "user@example.com";
			const string etalonDisplayName = "User";
			const string fakePassword = "password";

			var environment = new TestEnvironment();

			var registrationService = environment
				.CreateRegistrationService();

			var result = registrationService.Register(etalonEmail, etalonDisplayName, fakePassword);

			Assert.Equal(RegistrationResultCode.Success, result.Code);
			Assert.NotNull(result.Account.Person);
			Assert.NotEmpty(environment.PersonRepository.Storage);
			Assert.Equal(etalonEmail, environment.PersonRepository.Storage[0].EmailAddress);
			Assert.Equal(etalonDisplayName, environment.PersonRepository.Storage[0].DisplayName);
		}

		[Fact]
		public void Should_Faile_When_Person_With_Same_Email_Exists()
		{
			const string etalonEmail = "user@example.com";
			const string fakeDisplayName = "User";
			const string fakePassword = "password";

			// Prepare environment with exisiting person
			var environment = new TestEnvironment();
			Account exisitingAccount =
				new Account
					{
						Person =
							new Person
								{
									EmailAddress = etalonEmail
								}
					};

			environment.AccountRepository.Storage.Add(exisitingAccount);

			var registrationService = environment
				.CreateRegistrationService();
			
			var result = registrationService
				.Register(etalonEmail, fakeDisplayName, fakePassword);

			Assert.Equal(RegistrationResultCode.AccountWithEmailExists, result.Code);
			Assert.Null(result.Account);
		}
	}
}
